package com.icloud.system.boot.controller.app;

import com.icloud.auth.api.vo.Oauth2TokenVo;
import com.icloud.common.core.api.CommonResult;
import com.icloud.common.core.api.ResultCode;
import com.icloud.common.web.annotation.AppWhiteListOperationLog;
import com.icloud.common.web.exception.Asserts;
import com.icloud.common.web.util.AuthUtil;
import com.icloud.system.boot.dto.LoginDto;
import com.icloud.system.boot.dto.ResetPasswordDto;
import com.icloud.system.boot.dto.UpdatePasswordDto;
import com.icloud.system.boot.service.AppCustomerAuthService;
import com.icloud.system.boot.service.GoogleAuthenticatorService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@Api(tags = "客户认证服务")
@RequestMapping("/app/auth")
@RequiredArgsConstructor
@Slf4j
public class CustomerAuthController {
    private final AppCustomerAuthService appCustomerAuthService;
    private final AuthUtil authUtil;
    private final GoogleAuthenticatorService googleAuthenticatorService;

    @ApiOperation(value = "客户登录")
    @AppWhiteListOperationLog("客户登录")
    @PostMapping(value = "/login")
    @ResponseBody
    public CommonResult<Oauth2TokenVo> login(@Validated @RequestBody LoginDto dto) {
        return appCustomerAuthService.appCustomerLogin(dto.getUsername(), dto.getPassword());
    }

    @ApiOperation(value = "客户登出")
    @PostMapping(value = "/logout")
    @ResponseBody
    public CommonResult<Boolean> logout() {
        return appCustomerAuthService.appCustomerLogout();
    }

    @ApiOperation("修改密码")
    @PutMapping(value = "/update/password")
    public CommonResult<Boolean> updatePassword(@Validated @RequestBody UpdatePasswordDto dto) {
        //验证两次输入的密码是否一致
        Asserts.fail(!dto.getPassword().equals(dto.getConfirmPassword()), ResultCode.PASSWORD_ENTERED_TWICE_NOT_MATCH);
        return CommonResult.success(appCustomerAuthService.updatePasswordById(authUtil.getUserId(), dto.getPassword()));
    }

    @ApiOperation("重置密码")
    @PutMapping(value = "/reset/password")
    public CommonResult<Boolean> resetPassword(@Validated @RequestBody ResetPasswordDto dto) {
        //验证两次输入的密码是否一致
        Asserts.fail(!dto.getPassword().equals(dto.getConfirmPassword()), ResultCode.PASSWORD_ENTERED_TWICE_NOT_MATCH);
        return CommonResult.success(appCustomerAuthService.resetPasswordById(dto.getId(), dto.getMnemonics(), dto.getPassword()));
    }

    @ApiOperation(value = "根据助记词查找账号Id")
    @GetMapping(value = "/find/customer/mnemonics")
    @ResponseBody
    public CommonResult<Long> findCustomerByMnemonics(@RequestParam("mnemonics") String mnemonics) {
        return CommonResult.success(appCustomerAuthService.findCustomerByMnemonics(mnemonics));
    }

    @ApiOperation("修改交易密码")
    @PutMapping(value = "/update/txPassword")
    public CommonResult<Boolean> updateTxPassword(@Validated @RequestBody UpdatePasswordDto dto) {
        //验证两次输入的密码是否一致
        Asserts.fail(!dto.getPassword().equals(dto.getConfirmPassword()), ResultCode.PASSWORD_ENTERED_TWICE_NOT_MATCH);
        return CommonResult.success(appCustomerAuthService.updateTxPasswordById(authUtil.getUserId(), dto.getPassword()));
    }

    @ApiOperation("生成双因子二维码")
    @PostMapping(value = "/qrcode/gen")
    public CommonResult<Void> genQrcode(@RequestParam("username") String username, HttpServletResponse response) {
        try (ServletOutputStream stream = response.getOutputStream()) {
            googleAuthenticatorService.genQRImage(username, stream);
        } catch (IOException e) {
            log.error("生成二维码出错: ", e);
            return CommonResult.failed();
        }
        return CommonResult.success();
    }

    @ApiOperation("生成双因子url")
    @PostMapping(value = "/qrurl/gen")
    @ResponseBody
    public CommonResult<String> genQrUrl(@RequestParam("username") String username) {
        return CommonResult.success(googleAuthenticatorService.getQrUrl(username));
    }

    @ApiOperation("双因子验证")
    @GetMapping("/twoFactoryVerify")
    @ResponseBody
    public CommonResult<Boolean> twoFactoryVerify(@RequestParam("username") String username, @RequestParam("code") int code) {
        //String dateTime = LocalDateTime.now(ZoneOffset.of("+8")).format(CommonConstant.DEFAULT_DATETIME_FORMATTER);
        boolean result = googleAuthenticatorService.validCode(username, code);
        //log.info("verify end: {}-{}, result:{}", code, dateTime, result);
        return CommonResult.success(result);
    }
}
